package com.yz.util;

/**
 * @Author: milk_ape
 * @Date: 2019/3/5 9:33
 * @Version 1.0
 */
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yz.hoo.HooUtil;
import org.apache.commons.codec.binary.Hex;
import sun.misc.BASE64Decoder;

import java.util.TreeMap;

//对接充币到账接口的sign验签demo
public class UpRSA {
    public static final String KEY_ALGORITHM = "RSA";

    public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";

    //test publicKey
    public static String publicStr="MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6cERcDUahTn9NiBC6eOw+d0hQI265lSwOkA8MnRhS0c6ZZOvmHsi8ElMV1ZuugbI9YIxS55938w7vhSi040bqk27TDvgJsi7wYSrrBz48WeSQ/CfmIZ8gKBA8QPXdvPcbAfdOgfFyEcdmrQGs60+RZCIRZJHWRlXUEI6ZnNPPBVWiRuk2me1tCDqc20pcmZIrs++XCoKkPeHO10iFW1uyqLcjHFVsKZ65gbOzh942SPhC3piT2WbDBYAG8tVGS1MdLpRWkjVUb1SYf2z4JBuaAweCtLUYUyU5YYUoqRb7+bPth50pCcnurfM5SQNjjcDGJiXVFItBMRXOypMPv4jCwkoPImApLpijfh91gdcWmIJNtzMG/JoraIT6xd7XZxeMMr6pBBdUwZykJCJYmytWlgnpxPErzEnbfu6q9hIlFCLBKNNrzh02MzdHp+CosPJzyW02X1YN/0aFQ5AA83mTy21AMosZBtbFNOoMyGa03nUTuBZCPxBSu1M8aTQ9OGCWCqDevwE3GHRofHWydP5XSCS3npjtM1EqTiAXPonSEyqj24kypN7kkMfHaXaHp6o1NdZmg2C3VyPf9sAY1AGfEnMw1LnQ5gzBk2i3HS4Xn5uORJjxnptqvWmz9nVvGHjfT8kjOW6fP3rAg6mTM7+EZw5i0WYqEJyZU+g2iJ/VGcCAwEAAQ==";

    public static String sign="0bf5febde13f60bbb1d6d7b939e922a70a81c1ba52a072cfe050acaed0ec11d8d6c0567cc177a51c2b5f493e80d264ea96d20a3cb9b0697eaa04ca87f214e39e2de9bd5d7fc6b981d34c56ce050d51227eb7a05644565a003a82f11c12da960bf96adb65c306508dab1d4cfb20cef0ae4221fdbedd1bf9ec65eea57a3d2f0643f350dd813aa34a11c4d209f1fe752b384c2cbb4c6874fa5afd0afa5b3eec36c2c061288e15f66c7a4389755c0b222d241448d86e1d0666084cab81de0b5515b3895914a7f38bf0b324e62b84c941dab37e6289f33d73d032a0d5af3148642617cb00acfc9285ce74fbdb0b7b056a9358f639e39466f98449abf30cd5831c3fd9b29d4156964f86149be17bbd0e686cbe59e560d9793c9a6e036c190d19816b1f5f165b8b28734e93bb63898f4f217eff6874d23069c88863b98764b9d4940b053f42901a82162f9f828fe0af246b8b114be18514b03f4d817cd3fbb9be92027f2aa16d10bb50c9e55372d87a4c548a204875a4da2d6d1fd308e79acde74891b13ed4480ca990710a09108b4b31941a1d4c6812edabaa7bcd8c1ff372913d71da2c16d767c74886bfa0ab5d12c9c0620f851395b710ed7236361d806b3f6d2e402bb5f0bae22b193674962759b9951457ccbf4b0d519d8b7e15a8917abd9e7b5ce41fac1513c16b32a3530d832a69ae2cb1b004ed363abb7966c7dced509ac079";



    /**
     * 公钥，X509EncodedKeySpec 用于构建公钥的规范
     *
     * @param keyBytes
     * @return PublicKey
     */
    public static PublicKey restorePublicKey(byte[] keyBytes) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);

        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     *验签
     *
     * @param key
     * @param encodedText
     * @return String test
     */
    public static String RSADecode(PublicKey key, byte[] encodedText) {

        try {
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            return new String(cipher.doFinal(encodedText));
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

    }

    /**
     *转换key
     *
     * @param key
     * @return key byte[]
     */
    public static byte[] decryptBASE64(String key) throws Exception{
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /***
     * 利用Apache的工具类实现SHA-256加密
     * @param str 加密后的报文
     * @return
     */
    public static String getSHA256Str(String str){
        MessageDigest messageDigest;
        String encdeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
            encdeStr = Hex.encodeHexString(hash);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encdeStr;
    }

    public static Map<String, String> sortMap(Map<String, String> map) {
	        if (map == null || map.isEmpty()) {
	            return null;
	        }
	        Map<String, String> sortMap = new TreeMap<String, String>(new MapComparator());
	        sortMap.putAll(map);
	        return sortMap;
    }

    static class MapComparator implements Comparator<String>{

        @Override
        public int compare(String str1, String str2) {
            // TODO Auto-generated method stub
            return str1.compareTo(str2);
        }

    }

    public static void main(String[] args) throws Exception {
        PublicKey publicKey = restorePublicKey(decryptBASE64(publicStr));
        // 公钥解密
        System.out.println("公钥解密==============: "+ RSADecode(publicKey, HooUtil.hexStrToBytes(sign)));//privateResult
                                                                        //{"amount":"0.0001000000","block_height":565156,"coin_type":"BTC","confirmations":"6","fee":"0.0001100000","from_address":"1Pjjz1ftQrSTcw4TL6AoRPeZhCHXZXQqq9","is_in":"1","memo":"","timestamp":1551420397,"to_address":"35ic6eZFjCWTqHSkfWpc8ghbc6eorVBXUV","transaction_id":"af8b25e7efdf448d196c21010b2642d4ddb5bf8e46d8e243c6431b2e8925d897","trx_n":0}
        System.out.println("sha256加密==============: "+ getSHA256Str("{\"amount\":\"0.0001000000\",\"block_height\":565156,\"coin_type\":\"BTC\",\"confirmations\":6,\"fee\":\"0.0001100000\",\"from_address\":\"1Pjjz1ftQrSTcw4TL6AoRPeZhCHXZXQqq9\",\"is_in\":1,\"memo\":\"\",\"timestamp\":1551420397,\"to_address\":\"35ic6eZFjCWTqHSkfWpc8ghbc6eorVBXUV\",\"transaction_id\":\"af8b25e7efdf448d196c21010b2642d4ddb5bf8e46d8e243c6431b2e8925d897\",\"trx_n\":0}"));

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("amount","0.0001000000");
        jsonObject.put("block_height",565156);
        jsonObject.put("coin_type","BTC");
        jsonObject.put("confirmations",6);
        jsonObject.put("fee","0.0001100000");
        jsonObject.put("from_address","1Pjjz1ftQrSTcw4TL6AoRPeZhCHXZXQqq9");
        jsonObject.put("is_in",1);
        jsonObject.put("memo","");
        jsonObject.put("timestamp",1551420397);
        jsonObject.put("to_address","35ic6eZFjCWTqHSkfWpc8ghbc6eorVBXUV");
        jsonObject.put("transaction_id","af8b25e7efdf448d196c21010b2642d4ddb5bf8e46d8e243c6431b2e8925d897");
        jsonObject.put("trx_n",0);
        //String s2=JSONObject.toJSONString(jsonObject,SerializerFeature.SortField.MapSortField);

        Map<String,String> map = JSON.parseObject(jsonObject.toString(),Map.class);
        Map<String, String> resultMap = sortMap(map);
        String result = JSON.toJSONString(resultMap);
        System.out.println("result:"+result);

        //{"amount":"0.0001000000","block_height":565156,"coin_type":"BTC","confirmations":"6","fee":"0.0001100000","from_address":"1Pjjz1ftQrSTcw4TL6AoRPeZhCHXZXQqq9","is_in":"1","memo":"","timestamp":1551420397,"to_address":"35ic6eZFjCWTqHSkfWpc8ghbc6eorVBXUV","transaction_id":"af8b25e7efdf448d196c21010b2642d4ddb5bf8e46d8e243c6431b2e8925d897","trx_n":0}


        System.out.println(getSHA256Str(result));

        /* String str = "2:1551406800:0e11f9ea04076a5f358d02b530a343b8df19d4cdee8e69d0e748218a4e34f3a90b2b04d9b9abad5a61ffb1e539ddb6e57ef6b1cb32e748c558fa968bc60842e91f9786f065bfcf65e1d0bd252d3c658ba9bfb497cea0d26367a6bc8707843e66e61347aec85229160259f3b9708b0181c6be68d6f49f55d58d1b3bd5b13fc301";
        String s[] = str.split(":");
        for (int i =0; i<s.length; i++) {
            System.out.println(i + " : " + s[i]);
        }
        String uid = s[0];
        String extime = s[1];
        String sign = s[2];
        String trx = uid+ ":" + extime + ":" + sign;
        System.out.println(trx);*/

    }
}
